package com.xxx.springboot.interceptor;

import java.io.IOException;
import java.io.PrintWriter;
import java.lang.reflect.Method;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import com.xxx.springboot.annotation.AutoIdempotent;
import com.xxx.springboot.pojo.Result;
import com.xxx.springboot.service.TokenService;

/**
 * 2.幂等拦截器
 * 使用redis的token进行幂等拦截处理
 * 添加到拦截器链：registry.addInterceptor(autoIdempotentInterceptor);
 * 参考：https://www.toutiao.com/i6816188855268409860
 */
@Component
public class AutoIdempotentInterceptor implements HandlerInterceptor {

	@Autowired
    private TokenService tokenService;
	
	/**
     * 预处理
     *
     * @param request
     * @param response
     * @param handler
     * @return
     * @throws Exception
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
    		throws Exception {

        if (!(handler instanceof HandlerMethod)) {
            return true;
        }
        
        HandlerMethod handlerMethod = (HandlerMethod) handler;
        Method method = handlerMethod.getMethod();
        
        // 扫描被@ApiIdempotment注解标记的方法
        AutoIdempotent methodAnnotation = method.getAnnotation(AutoIdempotent.class);
        if (methodAnnotation != null) {
            try {
            	// 幂等性校验, 校验通过则放行, 校验失败则抛出异常, 并通过统一异常处理返回友好提示
                return tokenService.checkToken(request);
            }catch (Exception e){
                writeReturnJson(response, Result.fail(101, e.getMessage()));
                throw e;
            }
        }
        
        //必须返回true,否则会被拦截一切请求
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {

    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {

    }

    /**
     * 返回的json值
     * @param response
     * @param json
     * @throws Exception
     */
    private void writeReturnJson(HttpServletResponse response, String json) throws Exception{
        PrintWriter writer = null;
        response.setCharacterEncoding("UTF-8");
        response.setContentType("text/html; charset=utf-8");
        try {
            writer = response.getWriter();
            writer.print(json);

        } catch (IOException e) {
        	e.printStackTrace();
        } finally {
            if (writer != null) {
                writer.close();
            }
        }
    }
    
}
